查看原文
其他

谷歌大神为你解释Kubernetes, 微服务和容器化

2017-12-14 王青 程序猿DD

来自谷歌云平台(Google Cloud Platform)的开发者布道师 Ray Tsang 和 Bret McGowen 在 SpringOne2GX 大会上分享了谷歌的 Kubernetes 的实践,来看看都有哪些内容吧!



微服务解决的痛点


1. 包的大小和部署的难度成正比
传统 Java 开发将应用打成一个巨无霸的 Ear 或者 War 文件(Fat Jar),包的大小越大,部署的复杂度就越高。

在传统架构中,通常开发人员需要给测试人员一个部署文档,而这个文档通常是一个很长的 Wiki 或者 Doc。开发将部署的每一步都描述在这个文档里,如果漏掉了其中任何一步,测试就可能部署不成功,所以包越大,你花在部署的时间就越长,这种做法对两者都是一种伤害。

微服务架构,每个 jar 包独立部署,且非常小,导致部署简单,依赖清晰。通过声明的方式将环境用代码来描述(Infra as Code),自动化搭建环境,而不是依赖文档。

2. 包越大,启动速度越慢
这个很好理解,包越大,需要加载的内容就越多,有的项目启动时间甚至需要半个小时。

使用微服务架构,服务启动速度快,并且能够实现0宕机滚动升级。

微服务的搭建


对于 Java 开发者,搭建微服务时建议使用 Spring Initializr (start.spring.io) 自动生成标准 Spring Boot 的框架代码,框架代码会声明所需要的依赖,例如 Mysql,Redis,Eureka,Zuul,Cloud messaging 等等,这样能够让开发者快速搭建一个微服务的项目,并且以此项目为规范,复制到其他项目,使得每个微服务的代码组织更规范,可读性更好。


如果不是 Spring 的开发者,也可以使用 Jboss Wildfly等其他微服务框架。


开始容器化

理论上来讲部署一个微服务,只需要执行 Java -jar 即可运行。但实际并没有人这么做,为什么?每个服务需要配置 JDBC 连接池,配置端口,做服务发现,服务隔离,如果人为的去维护每个微服务,那也将会是一场灾难。


容器和容器平台的诞生天生就能够解决这些问题。


1. 用代码描述环境 - DockerFile


DockerFile 解决的是用代码描述环境的问题。对这个 DockerFile 执行 Docker build 命令,可以构建出一个不变的镜像,这个镜像可以跑在任意的 Docker 环境里。这样就解决了基础设施即代码(Infra as Code)的问题。


2. 多容器应用的管理工具 - Compose

应用通常包含多个容器,Docker Compose 解决了应用里的多容器定义,运行的问题。 Compose 使用 YML 文件定义每个服务的依赖服务,自身暴露的端口等等。你只需要为你的微服务写好 YML 文件,然后执行 "docker-compose up", 那么你需要的所有容器都会启动起来,并且按照配置的方式去运行。


谷歌云平台的架构


在谷歌,所有的服务都跑在容器里,每周谷歌启动20亿次容器。



从谷歌开发者的视角来看容器平台,当开发者需要部署一个应用时,他只需要声明这个应用运行的集群,集群中机器的配置,以及服务的拷贝数量。



谷歌云平台 Kubernetes 架构图:

1. 容器镜像存储在私有 Docker 镜像注册中心(目前使用的是 Artifactory)。
2. 写好 Config 文件,让 Kubernetes Master 执行部署任务。
3. Scheduler 定时从 Master 取出任务,并且找到终端(Kubelet,通常是虚拟机)实际执行这个任务。
4. 当找到Kubelet 之后,从 Artifactory 拉取镜像,启动容器。

Kubernetes 的特性

如何实现类似谷歌的微服务架构?光靠 Compose 肯定不够,因为 Compose 仅仅解决了应用的描述,运行的问题,但应用的编排,服务注册,服务发现,服务监控,故障恢复,DNS,负载均衡等等功能如何实现? Docker 的作用是计算资源和环境的描述和调度,Kubernetes 的作用是以应用为中心的生命周期的管理。


 Pods


Pods 的定义:Pods 包含一组容器,容器之间共享 namespace,共享存储,共享 IP 地址。


为什么会有 Pods?Pods 设计的目标是为了支持需要紧耦合容器的应用,让一个 Pods 里的多个容器变成对外服务的原子结构。例如 LAMP应用,这个应用依赖于多个不同的容器才能运行。


Pods 主要的目的,是为了解决一些辅助程序,例如内容管理系统,本地缓存管理,日志,备份,代理和更新等等,目的是让这几个集成的容器有统一的生命周期,降低独立维护容器的复杂度,所以 Pods 的初衷并不是运行同一个容器的多个副本。


Replication Controller


Replication Controller 会将集群保持在一个期望的状态。


传统的部署,需要一步一步部署好所有需要的东西,在 Kubernetes 里,你只需要描述你要部署生什么样,例如我要将某个服务部署6个实例。


此时的环境里有6个实例,突然,Node2节点发生了故障,导致集群里有2个节点挂掉。在传统项目里,我需要监控这个事件,并且手动去重启节点。



Replication Controller 会自动监控到这个事故,并且在可以的节点里寻找可用资源,部署这两个实例,直到最终集群里有6个实例。



Service


Service 是一组 Pods 的逻辑集合。在 Service 内部,Kubernetes 会创建负载均衡来将流量代理到可用的 Pods 上。Service 有一个固定的虚拟 IP( VIP)对外提供服务。


Service 的应用场景在于:假设后端有3个容器实例在运行,并且这3个实例是随时有可能坏掉的(Design for failure),前端的实例无需关注这三个实例各自的状态,而只需要声明它依赖的是后端某一个 Service 即可,让 Replication Controller 自动保证这个后端 Service 的可用性。


Labels


和名字和 UID 不同,Labels 不提供唯一性,通常,我们期望多个对象使用相同的 Label(s)。通过 Label 的设置和消费,可以轻松的过滤出需要找到的对象,例如:



这个命令能够从集群中所有的 Pods 里找出环境属于"Production",tier 等于"frontend"的 Pods。在前端服务的依赖声明里,和执行 Deploy 命令时,都可以用到 Labels 这个特性,实现服务或 Pods 的过滤。

金丝雀(Canary)部署


金丝雀最早是矿工进煤矿时,会带一只金丝雀进去,如果金丝雀发生异常反应,则说明存在瓦斯泄露,如果金丝雀反应正常,则说明安全。


上图说明的是通过 Replication Controller,Labels 和 Service 实现金丝雀部署,通过 Label(Role=FE)找到 FE 服务的两个版本,V1和 V2,用 Service 来屏蔽版本的差异,并且将流量分发给 V1 和 V2 的 Pods。


谷歌内部的金丝雀发布的策略是将新的版本部署集群1%的机器,并且监控用户行为,如果用户对于新功能有更多的点击次数,则说明改功能可以部署更多实例,达到5-10%的比例,再根据监控结果决定是否部署到100%的机器。

服务发现

Kubernetes 里服务发现有多种方式:

1. 通过环境变量注入发现服务。
当 Pods 在集群的 Node 中运行时,Kubernetes 会为它增加一些列的环境变量。以 Redis 的服务发现为例:


上图的"redis-master"暴露了6379端口,以及在集群里的 IP 地址,如果你的容器声明了对"redis-master"服务的依赖,在你的 Pods 里就能够访问到这些环境变量。

2. 通过 Kubernetes DNS 服务器。
Kubernetes DNS 服务器会订阅 Kubernetes API创建 Service 的事件,并且为每个 Service 记录一个 DNS 的记录。这样做的好处是:只要 DNS 服务在集群里有访问权限,那么所有的 Pods 都能访问新注册的 Service。


举例:如果你有一个 Service 在 Kubernetes Namespace "my-ns"下 ,名字叫做叫 "my-service",那么一条叫做"my-service.my-ns"的记录就会被创建。所有在"my-ns" Namespace 里的 Pods 都能通过 DNS 查找到"my-service"。


总结


Pod: 一组紧耦合的容器。

Replication Controller:持续的将当前的状态变成期望的状态。

Service:一组 Pod 的逻辑组合。

Labels:将 Pods 打上标签,进行多纬度的分组。


通过 Kubernetes 的这些特性,您可以轻松实现服务的服务注册,服务发现,高可用性,故障自动回滚,金丝雀发布等需求,实现微服务的落地。


本文转载自公众号【JFrog杰蛙DevOps】

推荐阅读

我最常用的Intellij IDEA快捷键

最好用的 IntelliJ 插件 Top 10

Jenkins Pipeline插件十大最佳实践!

Spring Cloud Hystrix的请求合并

白话:服务降级与熔断的区别


点击 “阅读原文” 搜搜本号内容

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存